package hu.gar.web.user;

import hu.gar.common.service.RoleService;
import hu.gar.common.service.UserService;
import hu.gar.vo.RoleVO;
import hu.gar.web.util.CommonMessageUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

import org.primefaces.event.SelectEvent;
import org.primefaces.model.LazyDataModel;

@ManagedBean(name = "usersBean")
@ViewScoped
public class UsersBean implements Serializable {

	private static final long serialVersionUID = -9028033644517319633L;

	private LazyDataModel<UserDisplayVO> lazyModel;

	private UserDisplayVO selectedUser;

	private List<RoleVO> roles;
	private List<String> selectedRoles;

	@ManagedProperty("#{userService}")
	private UserService userService;

	@ManagedProperty("#{roleService}")
	private RoleService roleService;

	@PostConstruct
	public void init() {
		lazyModel = new LazyUserDataModel(userService);
		roles = getRoleService().getAllRole();
	}

	public void deleteUser() {
		try {
			Long userId = selectedUser.getId();
			List<RoleVO> roleVOs = userService.getRolesByUserId(userId);
			for (RoleVO roleVO : roleVOs) {
				userService.removeRoleFromUser(userId, roleVO.getId());
			}
			userService.removeUser(userId);
			CommonMessageUtil.addMessage(FacesMessage.SEVERITY_INFO, "succes");

		} catch (Exception e) {
			e.printStackTrace();
			CommonMessageUtil.addMessage(FacesMessage.SEVERITY_ERROR, "error");

		}
	}

	public void selectedItemsChanged(ValueChangeEvent event) {
		ArrayList<String> oldValue;
		if (event.getOldValue() == null) {
			oldValue = new ArrayList<String>();
		} else {
			oldValue = new ArrayList<String>((List<String>) event.getOldValue());
		}

		ArrayList<String> newValue = new ArrayList(
				(List<String>) event.getNewValue());

		String selectedItem;
		boolean selectedItemRemoved;
		if (oldValue.size() > newValue.size()) {
			oldValue = new ArrayList<String>(oldValue);
			oldValue.removeAll(newValue);
			selectedItem = oldValue.get(0);
			selectedItemRemoved = true;
		} else {
			newValue = new ArrayList<String>(newValue);
			newValue.removeAll(oldValue);
			selectedItem = newValue.get(0);
			selectedItemRemoved = false;
		}

		if (selectedItemRemoved) {
			try {
				userService.removeRoleFromUser(selectedUser.getId(), new Long(
						selectedItem));
				CommonMessageUtil.addMessage(FacesMessage.SEVERITY_INFO,
						"succes");

			} catch (Exception e) {
				e.printStackTrace();
				CommonMessageUtil.addMessage(FacesMessage.SEVERITY_ERROR,
						"error");

			}
		} else {
			try {
				userService.addRoleToUser(selectedUser.getId(), new Long(
						selectedItem));
				CommonMessageUtil.addMessage(FacesMessage.SEVERITY_INFO,
						"succes");

			} catch (Exception e) {
				e.printStackTrace();
				CommonMessageUtil.addMessage(FacesMessage.SEVERITY_ERROR,
						"error");

			}
		}
	}

	public LazyDataModel<UserDisplayVO> getLazyModel() {
		return lazyModel;
	}

	public UserDisplayVO getSelectedUser() {
		return selectedUser;
	}

	public void setSelectedUser(UserDisplayVO selectedUser) {
		this.selectedUser = selectedUser;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void setLazyModel(LazyDataModel<UserDisplayVO> lazyModel) {
		this.lazyModel = lazyModel;
	}

	public void onRowSelect(SelectEvent event) {
		FacesMessage msg = new FacesMessage("UserVO Selected:");

		FacesContext.getCurrentInstance().addMessage(null, msg);
		setSelectedRoles(new ArrayList<String>());
		List<RoleVO> roleVOs = userService.getRolesByUserId(selectedUser
				.getId());
		for (RoleVO roleVO : roleVOs) {
			getSelectedRoles().add(roleVO.getId().toString());
		}

	}

	public List<RoleVO> getRoles() {
		return roles;
	}

	public void setRoles(List<RoleVO> roles) {
		this.roles = roles;
	}

	public RoleService getRoleService() {
		return roleService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public List<String> getSelectedRoles() {
		return selectedRoles;
	}

	public void setSelectedRoles(List<String> selectedRoles) {
		this.selectedRoles = selectedRoles;
	}

}